Przejdź do głównej treści

Pierwszy krok w obliczenia kwantowe

  • Poziom trudności: Początkujący
  • Zużycie czasu QPU: 11s

Witaj, hackerze! Cieszymy się, że jesteś z nami na warsztatach. Głównym celem tego wprowadzającego ćwiczenia jest przygotowanie cię do kwantowej podróży poprzez: 1) przeprowadzenie cię przez instalację Qiskit, 2) utworzenie konta IBM Cloud oraz przygotowanie api_key i crn do korzystania z prawdziwego komputera kwantowego, 3) zbudowanie pierwszego Circuit kwantowego, 4) rozwiązanie quizu o stanach kwantowych oraz 5) uruchomienie twoich Circuit na prawdziwym komputerze kwantowym i wykreślenie wyników.

1. Najpierw najważniejsze: Qiskit

Czym jest Qiskit

Qiskit SDK to wydajny stos oprogramowania zbudowany, aby pomóc programistom i badaczom w pełnym wykorzystaniu mocy komputerów kwantowych w skali użytkowej i dalej. Jego rdzeniem jest Qiskit SDK – zestaw narzędzi programistycznych open source do pracy z komputerami kwantowymi na poziomie rozszerzonych Circuit kwantowych, operatorów i prymitywów. Qiskit SDK pozwala każdemu uzyskać optymalną wydajność z prawdziwych komputerów kwantowych w preferowanym środowisku obliczeniowym.

Oprócz samego SDK, Qiskit obejmuje również zestaw wydajnych narzędzi i usług, takich jak Qiskit Runtime Service, który umożliwia zoptymalizowane obliczenia na komputerach kwantowych IBM przez chmurę z wykorzystaniem prymitywów zarządzających mitygacją błędów. Usługa Qiskit Transpiler dostarcza najnowocześniejsze metody heurystyczne i oparte na AI, które zwiększają wydajność typowych zadań optymalizacji Circuit kwantowych.

Qiskit functions to katalog usług IBM i firm trzecich, które ułatwiają optymalizację obciążeń i wykorzystanie Qiskit w zastosowaniach branżowych. Niezależnie od tego, czy jesteś programistą oprogramowania kwantowego, eksperymentatorem kwantowym, naukowcem obliczeniowym, czy dopiero zaczynasz przygodę z tematem – modułowa i elastyczna architektura Qiskit pozwala ci pracować na poziomie abstrakcji najlepiej dopasowanym do twoich potrzeb.

Qiskit jest zaprojektowany z myślą o rozszerzalności i możliwości dostosowania, dzięki czemu możesz wyciągać wiodące w branży wyniki i podejmować nowe rodzaje problemów. Wydajna baza kodu sprawia, że Qiskit SDK działa szybciej, zużywa mniej pamięci i dostarcza lepsze rezultaty niż kiedykolwiek wcześniej. Qiskit wprowadza cię również do ogromnej społeczności użytkowników i deweloperów, którzy chętnie cię przyjmą i pomogą odpowiedzieć na twoje pytania. Uruchomiony po raz pierwszy w 2019 roku, program Qiskit Advocate to globalna, skupiona na społeczności inicjatywa skupiająca specjalistów i entuzjastów obliczeń kwantowych z całego świata. Z biegiem lat adwokaci stali się uznanymi liderami w społeczności kwantowej. Chcesz zostać następnym liderem kwantowym? Nie wahaj się aplikować – tutaj

Instalacja Qiskit

Najpierw sprawdź, czy wersja Pythona używana w Twoim środowisku to python>=3.10, aby upewnić się, że jest zgodna z najnowszą wersją Qiskit, której będziemy używać.

from platform import python_version

print(python_version())

Jeśli tak nie jest, możesz zaktualizować Pythona, używając preferowanego narzędzia. Jeśli nie wiesz jak to zrobić, oto kilka zalecanych opcji:

  • macOS: Homebrew
  • Linux: sudo apt-get update

Szczegółowy przewodnik dotyczący aktualizacji Pythona w zależności od systemu operacyjnego znajdziesz tutaj: Jak zaktualizować Pythona

Więcej informacji znajdziesz w wiki QGSS (Qiskit Global Summer School) 2025: https://github.com/qiskit-community/qgss-2025/wiki/Jupyter-Notebook-Environment-(Local-and-Online)

Możesz zweryfikować instalację, uruchamiając poniższą komórkę. Jeśli instalacja przebiegła poprawnie, zwróci ona wersję Qiskit.

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
%pip install 'qiskit[visualization]'
%pip install qiskit-ibm-runtime
%pip install qiskit-aer
import qiskit

print(f"Qiskit version: {qiskit.__version__}")

Rozwiązywanie problemów

Jeśli poprzednia komórka zgłosiła błąd, możesz zainstalować Qiskit w wirtualnym środowisku (poniżej dwie proponowane metody). Jeśli nie masz błędów, możesz pominąć tę komórkę i przejść do następnej.

Proponujemy dwie różne metody konfiguracji wirtualnego środowiska do instalacji Qiskit.

  1. Używając venv, zgodnie z opisem w przewodniku instalacji Qiskit.
  2. Używając conda, zgodnie z opisem w tym filmie z serii Coding with Qiskit.

2. Konfiguracja konta IBM Cloud

Aby korzystać z prawdziwego komputera kwantowego, potrzebujesz api key – głównego biletu wstępu do chmury – oraz crn – tokenu, który połączy cię z Twoimi zasobami poprzez skonfigurowanie konta.

Skonfiguruj swoje konto w następujący sposób:

  1. Przejdź do IBM Quantum® Platform.
  2. Przejdź do prawego górnego rogu (jak pokazano na powyższym zdjęciu), utwórz swój token API i skopiuj go w bezpieczne miejsce.
  3. W następnej komórce zastąp deleteThisAndPasteYourAPIKeyHere swoim kluczem API.
  4. Przejdź do lewego dolnego rogu (jak pokazano na powyższym zdjęciu) i utwórz swoją instancję. Pamiętaj, aby wybrać plan open.
  5. Po utworzeniu instancji skopiuj powiązany z nią kod CRN. Być może trzeba będzie odświeżyć stronę, aby zobaczyć instancję.
  6. W poniższej komórce zastąp deleteThisAndPasteYourCRNHere swoim kodem CRN.

Więcej szczegółów na temat konfiguracji konta IBM Cloud® znajdziesz w tym przewodniku.

⚠️ Uwaga: Traktuj swój klucz API jak bezpieczne hasło. Więcej informacji o używaniu klucza API zarówno w bezpiecznych, jak i niezaufanych środowiskach znajdziesz w przewodniku Cloud setup.

Dodatkowo, jeśli jesteś członkiem sieci partnerskiej IBM dla uczelni, użyj adresu e-mail swojej instytucji jako IBM ID, aby otrzymać korzyści partnerskie.

from qiskit_ibm_runtime import QiskitRuntimeService

# Save your API key and crn and have access to the quantum computers
your_api_key = "deleteThisAndPasteYourAPIKeyHere"
your_crn = "deleteThisAndPasteYourCRNHere"

QiskitRuntimeService.save_account(
channel="ibm_cloud",
token=your_api_key,
instance=your_crn,
overwrite=True
)
# Check that the account has been saved properly
service = QiskitRuntimeService()
service.saved_accounts()
# See backends you can use
service.backends()

3. twój pierwszy Quantum Circuit

Quantum circuits

Podstawową jednostką Qiskit jest quantum circuit, czyli seria instrukcji, które komputer kwantowy może wykorzystać do pracy z kwantowymi bitami informacji, zwanymi też qubitami. Qubitów mają szczególne właściwości, dzięki którym komputery kwantowe podchodzą do problemów inaczej niż twój laptop czy iPhone. Qiskit szybko się rozwija jako technologia — wciąż możesz ręcznie projektować swoje quantum circuits i decydować, jak mają być uruchamiane (i jest wiele dobrych powodów, by tak robić), ale IBM Quantum dostarcza też narzędzia upraszczające ten proces. W celach dydaktycznych zaprojektujemy bardzo prosty Circuit i uruchomimy go na symulatorze.

Przemykamy przez ten przegląd dość szybko, bo szczerze mówiąc, moglibyśmy spędzić godziny wyjaśniając same podstawy informacji i obliczeń kwantowych. IBM Quantum zrobił to już za nas, tworząc kurs pisemny i serię wykładów wideo poświęconych temu tematowi. Jeśli potrzebujesz odświeżyć wiedzę, zajrzyj tam!

from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector
from qiskit.visualization import plot_state_qsphere
from qiskit_aer import AerSimulator
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2 as Sampler
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.visualization import array_to_latex
from qiskit.visualization import plot_distribution

import numpy as np
from numpy import sqrt

Podstawowe operacje na Qubitach i pomiary

Zapisywanie stanów pojedynczego Qubitu

Zacznijmy od spojrzenia na pojedynczy Qubit. Główna różnica między klasycznym bitem, który może przyjmować wyłącznie wartości 0 i 1, polega na tym, że kwantowy bit, czyli qubit, może znajdować się w stanach 0\vert0\rangle, 1\vert1\rangle, a także w dowolnej liniowej kombinacji tych dwóch stanów. Właściwość ta nosi nazwę superpozycji i pozwala nam zapisać najbardziej ogólny stan qubitu jako:

ψ=1p0+eiϕp1\vert\psi\rangle = \sqrt{1-p}\vert0\rangle + e^{i \phi} \sqrt{p} \vert1\rangle

Gdybyśmy zmierzyli stan tego qubitu, otrzymalibyśmy wynik 11 z prawdopodobieństwem pp, a wynik 00 z prawdopodobieństwem 1p1-p. Jak widać, łączne prawdopodobieństwo wynosi 11, co oznacza, że rzeczywiście zmierzymy albo 00, albo 11 — żadne inne wyniki nie istnieją.

Oprócz pp mógłeś zauważyć jeszcze jeden parametr powyżej. Zmienna ϕ\phi oznacza względną fazę kwantową między stanami 0\vert0\rangle i 1\vert1\rangle. Jak odkryjemy później, ta względna faza jest całkiem ważna. Na razie wystarczy odnotować, że faza kwantowa umożliwia interferencję między stanami kwantowymi, co daje nam możliwość pisania algorytmów kwantowych do rozwiązywania konkretnych zadań.

Wizualizacja stanów kwantowych

Stany kwantowe wizualizujemy w tym ćwiczeniu za pomocą obiektu zwanego qsphere. Oto jak qsphere wygląda dla stanów 0\vert0\rangle i 1\vert1\rangle. Zauważ, że najwyższa część sfery odpowiada stanowi 0\vert0\rangle, a dolna — 1\vert1\rangle.

#visualize |0>
sv=Statevector([1, 0])
plot_state_qsphere(sv)

Dokładnie tę samą QSphere można uzyskać za pomocą quantum circuit. Wektor stanu, którego tu używamy, pochodzi ze stanu 0|0\rangle. W Qiskit qubit jest inicjalizowany w stanie 0|0\rangle. Spróbuj uruchomić poniższy Circuit i sprawdź, czy otrzymasz tę samą QSphere.

qc1 = QuantumCircuit(1)
sv=Statevector(qc1)
plot_state_qsphere(sv)

Teraz zwizualizujmy stan 1|1\rangle. Nie powinno dziwić, że stan superpozycji z fazą kwantową ϕ=0\phi = 0 i prawdopodobieństwem p=1/2p = 1/2 (czyli jednakowym prawdopodobieństwem pomiaru 0 i 1) jest pokazany na qsphere w postaci dwóch punktów. Zauważ jednak, że rozmiar kółek w tych dwóch punktach jest mniejszy niż w przypadku samego 0\vert0\rangle lub 1\vert1\rangle. Wynika to z tego, że rozmiar kółek jest proporcjonalny do prawdopodobieństwa pomiaru każdego ze stanów, które zostało teraz zmniejszone o połowę.

#visualize 1/sqrt(2)|0> + 1/sqrt(2)|1>

sv=Statevector([1/sqrt(2), 1/sqrt(2)])
plot_state_qsphere(sv)

W przypadku stanów superpozycji, w których faza kwantowa jest niezerowa, qsphere pozwala zwizualizować tę fazę poprzez zmianę koloru odpowiedniego "bloba". Na przykład stan z ϕ=90\phi = 90^\circ (stopni) i prawdopodobieństwem p=1/2p = 1/2 jest pokazany w qsphere poniżej.

sv=Statevector([1/sqrt(2), 1/sqrt(2)*1j])
plot_state_qsphere(sv)

Manipulowanie Qubitami

Qubitami manipuluje się przez zastosowanie kwantowych Gate'ów. Przyjrzyjmy się przeglądowi różnych Gate'ów, które rozważymy w kolejnych ćwiczeniach.

Najpierw opiszmy, jak możemy zmieniać wartość pp naszego ogólnego stanu kwantowego. W tym celu użyjemy dwóch Gate'ów:

  1. Gate XX: Ten Gate przełącza między stanami 0\vert0\rangle i 1\vert1\rangle. Operacja ta jest odpowiednikiem klasycznej bramki NOT. Dlatego Gate XX bywa nazywany bit flip lub bramką NOT. Matematycznie Gate XX zmienia pp na 1p1-p, a w szczególności z 0 na 1 i odwrotnie.

  2. Gate HH: Ten Gate pozwala przejść ze stanu 0\vert0\rangle do stanu 12(0+1)\frac{1}{\sqrt{2}}\left(\vert0\rangle + \vert1\rangle\right). Stan ten jest też znany jako +\vert+\rangle. Matematycznie oznacza to przejście z p=0,ϕ=0p=0, \phi=0 do p=1/2,ϕ=0p=1/2, \phi=0. Ponieważ końcowy stan qubitu jest superpozycją 0\vert0\rangle i 1\vert1\rangle, Gate Hadamarda reprezentuje prawdziwą operację kwantową.

Zauważ, że oba Gate'y zmieniły wartość pp, ale nie ϕ\phi. Na szczęście działanie tych Gate'ów jest dość łatwe do zwizualizowania na poniższym rysunku.

Mając stan +\vert+\rangle, możemy następnie zmieniać fazę kwantową, stosując inne Gate'y. Na przykład Gate SS dodaje fazę 9090 stopni do ϕ\phi, podczas gdy Gate ZZ dodaje fazę 180180 stopni do ϕ\phi. Aby odjąć fazę 9090 stopni, możemy zastosować Gate SS^\dagger, który czyta się jako S-dagger i powszechnie zapisuje jako sdg. Na koniec jest Gate YY, który stosuje sekwencję Gate'ów ZZ i XX.

Możesz eksperymentować z Gate'ami XX, YY, ZZ, HH, SS i SS^\dagger, aby zapoznać się z różnymi operacjami i ich wpływem na stan qubitu. W tym celu możesz odwiedzić Circuit Composer i uruchomić nasz widżet obwodu. Po wejściu do Circuit Composera wybierz Gate do zastosowania na qubicie, a następnie wybierz qubit (w pierwszych przykładach jedynym dostępnym jest qubit 0). Obserwuj, jak odpowiedni stan zmienia się wraz z każdym Gate'em, a także opis tego stanu. Narzędzie dostarczy ci też kod tworzący odpowiedni quantum circuit w Qiskit.

Jeśli chcesz dowiedzieć się więcej o opisywaniu stanów kwantowych, operatorach Pauliego i innych Gate'ach jednoQubitowych, zapoznaj się z materiałem Quantum Information w sekcji Single System kursu Basics of Quantum Information autorstwa Johna Watrouse.

Ćwiczenia: Quantum Circuits z użyciem jednoqubitowych Gate'ów

Oto cztery małe ćwiczenia polegające na osiągnięciu różnych stanów na qsphere. Możesz je rozwiązać za pomocą Circuit Composera, skopiować i wkleić wygenerowany kod do odpowiednich komórek, aby stworzyć quantum circuits, albo bezpośrednio wstawić kombinację poniższych linii kodu do programu i zastosować różne Gate'y:

qc.x(0) # bit flip qc.y(0) # bit and phase flip qc.z(0) # phase flip qc.h(0) # superpostion qc.s(0) # quantum phase rotation by pi/2 (90 degrees) qc.sdg(0) # quantum phase rotation by -pi/2 (90 degrees)

Symbol '(0)' wskazuje, że stosujemy ten Gate na qubicie 'q0', czyli pierwszym (a w tym przypadku jedynym) qubicie.

Staraj się osiągnąć dany stan na qsphere w każdym z poniższych ćwiczeń.

i) Zacznijmy od bit flipa. Celem jest osiągnięcie stanu 1\vert1\rangle wychodząc ze stanu 0\vert0\rangle.


def create_circuit():
qc = QuantumCircuit(1)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc

# check solution
qc2 = create_circuit()
state = Statevector(qc2)

plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True)

ii) Teraz stwórzmy superpozycję. Celem jest osiągnięcie stanu +=12(0+1)|+\rangle = \frac{1}{\sqrt{2}}\left(|0\rangle + |1\rangle\right).


def create_circuit2():
qc = QuantumCircuit(1)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc

qc3 = create_circuit2()
state = Statevector(qc3)
plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True)

iii) Połączmy oba poprzednie. Celem jest osiągnięcie stanu =12(01)|-\rangle = \frac{1}{\sqrt{2}}\left(|0\rangle - |1\rangle\right).

Czy możesz połączyć powyższe dwa zadania, aby uzyskać rozwiązanie?

def create_circuit3():
qc = QuantumCircuit(1)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc

qc4 = create_circuit3()
state = Statevector(qc4)
plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True)

iv) Na koniec przechodzimy do liczb zespolonych. Celem jest osiągnięcie stanu =12(0i1)|\circlearrowleft\rangle = \frac{1}{\sqrt{2}}\left(|0\rangle - i|1\rangle\right)

def create_circuit4():
qc = QuantumCircuit(1)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc

qc5 = create_circuit4()
state = Statevector(qc5)

plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True)

4. Quantum Quiz z Bramkami Wieloqubitowymi

Świetna robota! Teraz, gdy rozumiesz już bramki jednoqubitowe, przyjrzyjmy się bramkom działającym na wielu Qubitach. Twoim zadaniem będzie rozwiązanie 4 quizów dotyczących stanów kwantowych, łącząc bramki jednoqubitowe i wieloqubitowe. Podstawowe bramki na dwóch Qubitach są następujące:

qc.cx(c,t) # controlled-X (= CNOT) gate with control qubit c and target qubit t qc.cz(c,t) # controlled-Z gate with control qubit c and target qubit t qc.swap(a,b) # SWAP gate that swaps the states of qubit a and qubit b

Jeśli chcesz dowiedzieć się więcej o różnych bramkach wieloqubitowych i ich wzajemnych powiązaniach, odwiedź Quantum Information o układach wielocząsteczkowych, z kursu Johna Basics of Quantum Information.

Zwróć uwagę, że dla dwóch Qubitów ogólny stan ma postać a00+b01+c10+d11a|00\rangle + b |01\rangle + c |10\rangle + d|11\rangle, gdzie aa, bb, cc i dd są liczbami zespolonymi, których kwadraty wartości bezwzględnych dają prawdopodobieństwo zmierzenia odpowiedniego stanu; np. a2|a|^2 byłoby prawdopodobieństwem zakończenia w stanie '0' na obu Qubitach. Oznacza to, że na sferze qsphere może teraz pojawić się nawet cztery punkty.

Zaczynamy od kanonicznej bramki dwuqubitowej – bramki kontrolowanej-NOT (zwanej też CNOT lub CX). Tutaj, podobnie jak w przypadku wszystkich kontrolowanych bramek dwuqubitowych, jeden Qubit jest oznaczony jako „sterujący" (control), a drugi jako „docelowy" (target). Jeśli Qubit sterujący jest w stanie 0|0\rangle, na Qubit docelowy stosowana jest bramka tożsamości II, czyli nie jest wykonywana żadna operacja. Natomiast jeśli Qubit sterujący jest w stanie 1|1\rangle, na Qubit docelowy stosowana jest bramka X. Zatem gdy oba Qubity są w jednym z dwóch klasycznych stanów, 0|0\rangle lub 1|1\rangle, bramka CNOT ogranicza się do operacji klasycznych.

Sytuacja zmienia się dramatycznie, gdy najpierw przyłożymy bramkę Hadamarda do Qubitu sterującego, wprowadzając go w stan superpozycji +|+\rangle. Działanie bramki CNOT na takie nieklasyczne wejście może tworzyć silnie splątane stany między Qubitem sterującym a docelowym. Jeśli Qubit docelowy jest początkowo w stanie 0|0\rangle, wynikowy stan jest oznaczany przez Φ+|\Phi^+\rangle i jest jednym z tak zwanych stanów Bella.

i) Skonstruuj stan Bella Φ+=12(00+11)|\Phi^+\rangle = \frac{1}{\sqrt{2}}\left(|00\rangle + |11\rangle\right).

Dla tego stanu prawdopodobieństwo zmierzenia „00" wynosi 12\frac{1}{2}, a prawdopodobieństwo zmierzenia „11" wynosi 12\frac{1}{2}. Tym samym wyniki obu Qubitów są doskonale skorelowane.


def create_circuit5():
qc = QuantumCircuit(2)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc

qc6 = create_circuit5()
state = Statevector(qc6) # determine final state after running the circuit
display(array_to_latex(state))
display(plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True))
qc6.draw(output='mpl') # we draw the circuit

Następnie spróbuj stworzyć stan doskonale antyskorelowanych Qubitów. Zwróć uwagę na znak minus, który wskazuje fazę względną między dwoma stanami.

ii) Skonstruuj stan Bella Ψ=12(0110)\vert\Psi^-\rangle = \frac{1}{\sqrt{2}}\left(\vert01\rangle - \vert10\rangle\right).


def create_circuit6():
qc = QuantumCircuit(2)
#
#
# FILL YOUR CODE IN HERE
#
#
return qc

qc7 = create_circuit6()
state = Statevector(qc7) # determine final state after running the circuit
display(array_to_latex(state))
display(plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True))
qc7.draw(output='mpl') # we draw the circuit

iii) Dana jest poniżej w funkcji obwód kwantowy. Zamień stany pierwszego i drugiego Qubitu, aby uzyskać tę QSphere.

def create_circuit7():
qc = QuantumCircuit(2)
qc.rx(np.pi/3,0)
qc.x(1)
return qc

qc8 = create_circuit7()

#
#
# FILL YOUR CODE IN HERE
#
#

state = Statevector(qc8) # determine final state after running the circuit
display(array_to_latex(state))
display(plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True))
qc8.draw(output='mpl') # we draw the circuit

iv) Napisz od podstaw program tworzący stan GHZ (na trzech Qubitach), GHZ=12(000+111)\vert \text{GHZ}\rangle = \frac{1}{\sqrt{2}} \left(|000\rangle + |111 \rangle \right)


def create_circuit8():
#
#
# FILL YOUR CODE IN HERE
#
#
#
return qc

qc9 = create_circuit8()

pub4 = (qc9)

state = Statevector(qc9) # determine final state after running the circuit
display(array_to_latex(state))
display(plot_state_qsphere(state, show_state_labels=True, show_state_phases = True, use_degrees = True))
qc9.draw(output='mpl') # we draw the circuit

5. Uruchom swój Circuit i sprawdź wynik pomiaru na prawdziwym komputerze kwantowym

Teraz, gdy wiemy już jak zbudować Circuit kwantowy do manipulowania statevektorem Qubitów, nadszedł czas na najbardziej ekscytującą część: uruchomienie go i zobaczenie wyników! Tutaj poznamy nowoczesny i skuteczny sposób wykonywania naszych circuitów przy użyciu Qiskit.

Wzorzec Qiskit (Qiskit pattern) to ogólny framework służący do rozkładania problemów domenowych na etapy i kontekstualizacji wymaganych możliwości. Pozwala to na płynne komponowanie nowych możliwości opracowywanych przez badaczy IBM Quantum (i innych) oraz otwiera drogę do przyszłości, w której zadania obliczeniowe na komputerach kwantowych będą wykonywane przez wydajną, heterogeniczną infrastrukturę obliczeniową (CPU/GPU/QPU).

Cztery kroki wzorca Qiskit są następujące:

  1. Odwzorowanie problemu na Circuit kwantowe i operatory
  2. Optymalizacja pod kątem docelowego sprzętu
  3. Wykonanie na docelowym sprzęcie
  4. Post-procesowanie wyników

Właśnie ukończyliśmy Krok 1: Odwzorowanie, budując Circuit kwantowe w celu wygenerowania pożądanego stanu kwantowego. Teraz przejdźmy przez pozostałe kroki, aby zobaczyć wyniki.

Optimize

Tutaj ustawimy Backend do uruchamiania circuitów — możesz wybrać najmniej obciążony QPU spośród dostępnych grup QPU lub po prostu wybrać symulator, jeśli nie masz wystarczającej pozostałej ilości czasu GPU. Po wybraniu Backendu, pass_manager dokona transpilacji twoich circuitów do natywnych zestawów bramek wybranego Backendu i zoptymalizuje je, aby uzyskać lepszy wynik. Możesz łatwo zadeklarować pass_manager, używając generate_preset_pass_manager i ustawiając optimization_level — wyższa liczba oznacza więcej kroków optymalizacji.

Następny krok jest ekscytujący — zamierzamy uruchomić Circuit kwantowy przy użyciu Qiskit Runtime!

Zrobimy to, korzystając z dwóch prymitywów Qiskit:

  1. Sampler próbkuje rejestr wyjściowy z wykonania jednego lub więcej Circuit kwantowych. Jego wynikiem są liczniki pomiarów per-shot.
  2. Estimator oblicza wartość oczekiwaną jednego lub więcej obserwowalnych względem stanów wygenerowanych przez Circuit kwantowy. Jego wynikiem są wartości oczekiwane wraz z ich błędami standardowymi.

Tutaj użyjemy Sampler do wykonania naszych circuitów. Poniższa komórka kodu pokazuje, jak najpierw zdefiniować Backend i pass manager dla niego. Następnie doda measurement do wszystkich circuitów i utworzy tablicę Circuit kwantowych (pub), którą przekażemy do Samplera.


backend=service.least_busy()
#backend=AerSimulator()

pm = generate_preset_pass_manager(optimization_level=3, backend=backend)
sampler = Sampler(mode=backend)

pub = []
for qc in circ:
qc.measure_all()
pub.append(pm.run(qc))

Execute

Wykonajmy nasze Circuit. Jeśli w chmurze jest wiele oczekujących zadań w kolejce, wydrukuj i zapisz job_id do późniejszego użycia oraz sprawdź status zadania. Po tym jak zobaczysz, że status zadania zmienił się na Done, pobierz wynik zadania.

job = sampler.run(pub)
job_id = job.job_id()
print(job_id)
job.status()
job_retrived = service.job(job_id)
result = job.result()

Post-process

Ostatnim krokiem jest interpretacja wizualizacji w celu zrozumienia stworzonych przez nas stanów kwantowych. Przed narysowaniem kilku wykresów zbierzmy wszystkie liczniki ze wszystkich circuitów. Następnie przygotujemy 4 wykresy, kategoryzując Circuit.

result = job.result()
counts_all = [result[k].data.meas.get_counts() for k in range(9)]

Stany jednego Qubita

plot_distribution([counts_all[0], counts_all[1]], legend =['qc1', 'qc2'])

Stany jednego Qubita w superpozycji

plot_distribution([counts_all[2], counts_all[3], counts_all[4]], legend =['qc3', 'qc4', 'qc5'])

Stany dwóch Qubitów

plot_distribution([counts_all[5], counts_all[6], counts_all[7]],legend =['qc6', 'qc7', 'qc8'] )

Stany trzech Qubitów

plot_distribution(counts_all[8], legend=['qc9'])

Dodatkowe wyzwanie

Czy zauważyłeś jakiś szum w wynikach eksperymentów na prawdziwym Backendzie? Eliminowanie szumów Qubitów to jeden z aktywnych obszarów badań. Wypróbuj różne opcje mitygacji i tłumienia błędów w Qiskit Runtime, aby zobaczyć, jak zmienia się szum w wynikach wykonania! (Uwaga) Opcje te wymagają większej ilości czasu QPU.

Dodatkowe informacje

import qiskit, qiskit_ibm_runtime

print("Qiskit version:", qiskit.version.get_version_info())
print("Qiskit Runtime version:", qiskit_ibm_runtime.__version__)
Qiskit version: 2.1.1
Qiskit Runtime version: 0.40.1

Autor: Sophy Shin

Recenzja: Nate Earnest-Noble

© IBM Corp., 2025

This is licensed under the Apache License, Version 2.0. You may obtain a copy of this license in the LICENSE file in the root directory of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

Any modifications or derivative works of this must retain this copyright notice, and modified files need to carry a notice indicating that they have been altered from the originals.